/*!
    \file    change log.txt
    \brief   change log for GD32F50x firmware

    \version 2026-02-25, V1.0.4, firmware for GD32F50x
*/

/*
    Copyright (c) 2026, GigaDevice Semiconductor Inc.

    Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this 
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice, 
       this list of conditions and the following disclaimer in the documentation 
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors 
       may be used to endorse or promote products derived from this software without 
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
*/

******************* V1.0.4 2026-02-25 ************************************************************************************
______________________Common______________________________________________________________________________________________
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/GCC/startup_gd32f50x.S
Fix reason:
modfi EB project FPU config
V1.0.3:
  .fpu softvfp
V1.0.4:
  .fpu fpv5-sp-d16
  
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/GCC/startup_gd32f50x.S
Fix reason:
change gcc startip file LVD_IRQHandler to LVD_VAVD_IRQHandler
V1.0.3:
LVD_IRQHandler    
V1.0.4:
LVD_VAVD_IRQHandler 
  
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/ARM/startup_gd32f50x.s
/fw3223X/GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/GCC/startup_gd32f50x.S
/fw3223X/GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/IAR/startup_gd32f50x.s
Fix reason:
The logical offset error of Option Bytes reading has been corrected
V1.0.3:
                 LDR     R5, [R4]
                 LSR     R5, R5, #2
                 ANDS    R5, R5, #0x3
                 CMP     R5, #0x3   
V1.0.4:
                 LDR     R5, [R4]
                 LSR     R5, R5, #3
                 ANDS    R5, R5, #0x3
                 CMP     R5, #0x3
  
____________________________________________________________________________________________________________________
______________________DAC______________________________________________________________________________________________
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_dac.h
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_dac.c
Fix reason:
3223X change dac_interrupt_enable, dac_interrupt_disable, dac_interrupt_flag_clear, dac_interrupt_flag_get, dac_flag_clear, dac_flag_get
____________________________________________________________________________________________________________________
______________________DBG______________________________________________________________________________________________
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_dbg.h
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_dbg.c
Fix reason:
Delete the DBG_CTL_TRACE_MODE BITS(6,7) bit field macro and related function macros as well as the corresponding functions(void dbg_trace_pin_mode_set(uint32_t trace_mode);)
_______________________________________________________________________________________________________________
______________________FWDGT______________________________________________________________________________________________
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_fwdgt.c
/fw3223X/GD32F50x_Firmware_Library/Examples/FWDGT/FWDGT_key/main.c
Fix reason:
Change fwdgt_prescaler_value_config, fwdgt_reload_value_config, fwdgt_config

Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_fwdgt.c
Fix reason:
delete #define WND_WND(regval)

Fix file:
/fw3223X/GD32F50x_Firmware_Library/Examples/FWDGT/FWDGT_key/main.c
Fix reason:
Change IRC32K to IRC40K 
V1.0.3:
    /* confiure FWDGT counter clock: 32KHz(IRC32K) / 64 = 0.5 KHz */
    fwdgt_config(2 * 500, FWDGT_PSC_DIV64);    
V1.0.4:
    /* confiure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
    fwdgt_config(2 * 625, FWDGT_PSC_DIV64);

____________________________________________________________________________________________________________________
______________________CAN______________________________________________________________________________________________
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_can.c
Fix reason:
Fixed the bug of CAN message cancellation caused by IC design
V1.0.3:
    if(CAN_MAILBOX0 == mailbox_number) {
        if((CAN_CTL_TFO == (CAN_CTL(can_periph) & CAN_CTL_TFO)) && (CAN_TSTAT_TMLS0 == (CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS0 | CAN_ALL_MAILBOX_EMPTY)))){
            reval = ERROR;
        } else {
	...
    } else if(CAN_MAILBOX1 == mailbox_number) {
        if((CAN_CTL_TFO == (CAN_CTL(can_periph) & CAN_CTL_TFO)) && (CAN_TSTAT_TMLS1 == (CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS1 | CAN_ALL_MAILBOX_EMPTY)))){
            reval = ERROR;
        }else{
    ...
    } else if(CAN_MAILBOX2 == mailbox_number) {
        if((CAN_CTL_TFO == (CAN_CTL(can_periph) & CAN_CTL_TFO)) && (CAN_TSTAT_TMLS2 == (CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS2 | CAN_ALL_MAILBOX_EMPTY)))){
            reval = ERROR;
        }else{
		
V1.0.4:
    uint32_t reg_value0 = 0U;
    uint32_t reg_value1 = 0U;

    /* get the status of transmit FIFO order */
    reg_value0 = CAN_CTL(can_periph) & CAN_CTL_TFO;

    if(CAN_MAILBOX0 == mailbox_number) {
        reg_value1 = CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS0 | CAN_ALL_MAILBOX_EMPTY);
        if((CAN_CTL_TFO == reg_value0) && (CAN_TSTAT_TMLS0 == reg_value1)){
            reval = ERROR;
        } else {
    ...
    } else if(CAN_MAILBOX1 == mailbox_number) {
        reg_value1 = CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS1 | CAN_ALL_MAILBOX_EMPTY);
        if((CAN_CTL_TFO == reg_value0) && (CAN_TSTAT_TMLS1 == reg_value1)){
            reval = ERROR;
        }else{
    ...
    } else if(CAN_MAILBOX2 == mailbox_number) {
        reg_value1 = CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS2 | CAN_ALL_MAILBOX_EMPTY);
        if((CAN_CTL_TFO == reg_value0) && (CAN_TSTAT_TMLS2 == reg_value1)){
            reval = ERROR;
        }else{
		
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_can.h
Fix reason:
Added more BS1 definition according to BS1's range
V1.0.3:	
#define CAN_BT_BS1_32TQ                    ((uint8_t)0x1FU)             /*!< 32 time quanta */
V1.0.4:	
#define CAN_BT_BS1_32TQ                    ((uint8_t)0x1FU)             /*!< 32 time quanta */
#define CAN_BT_BS1_33TQ                    ((uint8_t)0x20U)             /*!< 33 time quanta */
#define CAN_BT_BS1_34TQ                    ((uint8_t)0x21U)             /*!< 34 time quanta */
#define CAN_BT_BS1_35TQ                    ((uint8_t)0x22U)             /*!< 35 time quanta */
#define CAN_BT_BS1_36TQ                    ((uint8_t)0x23U)             /*!< 36 time quanta */
#define CAN_BT_BS1_37TQ                    ((uint8_t)0x24U)             /*!< 37 time quanta */
#define CAN_BT_BS1_38TQ                    ((uint8_t)0x25U)             /*!< 38 time quanta */
#define CAN_BT_BS1_39TQ                    ((uint8_t)0x26U)             /*!< 39 time quanta */
#define CAN_BT_BS1_40TQ                    ((uint8_t)0x27U)             /*!< 40 time quanta */
#define CAN_BT_BS1_41TQ                    ((uint8_t)0x28U)             /*!< 41 time quanta */
#define CAN_BT_BS1_42TQ                    ((uint8_t)0x29U)             /*!< 42 time quanta */
#define CAN_BT_BS1_43TQ                    ((uint8_t)0x2AU)             /*!< 43 time quanta */
#define CAN_BT_BS1_44TQ                    ((uint8_t)0x2BU)             /*!< 44 time quanta */
#define CAN_BT_BS1_45TQ                    ((uint8_t)0x2CU)             /*!< 45 time quanta */
#define CAN_BT_BS1_46TQ                    ((uint8_t)0x2DU)             /*!< 46 time quanta */
#define CAN_BT_BS1_47TQ                    ((uint8_t)0x2EU)             /*!< 47 time quanta */
#define CAN_BT_BS1_48TQ                    ((uint8_t)0x2FU)             /*!< 48 time quanta */
#define CAN_BT_BS1_49TQ                    ((uint8_t)0x30U)             /*!< 49 time quanta */
#define CAN_BT_BS1_50TQ                    ((uint8_t)0x31U)             /*!< 50 time quanta */
#define CAN_BT_BS1_51TQ                    ((uint8_t)0x32U)             /*!< 51 time quanta */
#define CAN_BT_BS1_52TQ                    ((uint8_t)0x33U)             /*!< 52 time quanta */
#define CAN_BT_BS1_53TQ                    ((uint8_t)0x34U)             /*!< 53 time quanta */
#define CAN_BT_BS1_54TQ                    ((uint8_t)0x35U)             /*!< 54 time quanta */
#define CAN_BT_BS1_55TQ                    ((uint8_t)0x36U)             /*!< 55 time quanta */
#define CAN_BT_BS1_56TQ                    ((uint8_t)0x37U)             /*!< 56 time quanta */
#define CAN_BT_BS1_57TQ                    ((uint8_t)0x38U)             /*!< 57 time quanta */
#define CAN_BT_BS1_58TQ                    ((uint8_t)0x39U)             /*!< 58 time quanta */
#define CAN_BT_BS1_59TQ                    ((uint8_t)0x3AU)             /*!< 59 time quanta */
#define CAN_BT_BS1_60TQ                    ((uint8_t)0x3BU)             /*!< 60 time quanta */
#define CAN_BT_BS1_61TQ                    ((uint8_t)0x3CU)             /*!< 61 time quanta */
#define CAN_BT_BS1_62TQ                    ((uint8_t)0x3DU)             /*!< 62 time quanta */
#define CAN_BT_BS1_63TQ                    ((uint8_t)0x3EU)             /*!< 63 time quanta */
#define CAN_BT_BS1_64TQ                    ((uint8_t)0x3FU)             /*!< 64 time quanta */		
____________________________________________________________________________________________________________________
______________________TIMER______________________________________________________________________________________________
Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_timer.h
Fix reason:
channel break enable and polarity modify
V1.0.3:
    uint32_t breakpolarity;                                                     /*!< BREAK input polarity */
}timer_break_parameter_struct;
V1.0.4:
    uint32_t breakpolarity;                                                     /*!< BREAK input polarity */
    uint32_t channelbreakstate;                                                 /*!< channel break input enable */
    uint32_t channelbreakpolarity;                                              /*!< channel break input polarity */
}timer_break_parameter_struct;

Fix file:
/fw3223X/GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_timer.c
/fw3223X/GD32F50x_Firmware_Library/Examples/TIMER/TIMER0_pwmout_complementarysignals_and_channel_break/main.c
Fix reason:
channel break enable and polarity modify
V1.0.3:
        breakpara->protectmode           = TIMER_CCHP0_PROT_OFF;
        breakpara->breakstate           = TIMER_BREAK_DISABLE;
        breakpara->breakfilter          = 0U;
        breakpara->breakpolarity        = TIMER_BREAK_POLARITY_LOW;
    }
}
...
*/
void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara)
{
#ifdef FW_DEBUG_ERR_REPORT
    if(NOT_VALID_POINTER(breakpara)) {
        fw_debug_report_err(TIMER_MODULE_ID, API_ID(0x001DU), ERR_PARAM_POINTER);
    } else
#endif /* FW_DEBUG_ERR_REPORT */
    {
        if((TIMER0 == timer_periph) || (TIMER7 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)) {
            TIMER_CCHP0(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate & TIMER_CCHP0_ROS)) |
                                                ((uint32_t)(breakpara->ideloffstate & TIMER_CCHP0_IOS)) |
                                                ((uint32_t)(breakpara->deadtime & TIMER_CCHP0_DTCFG)) |
                                                ((uint32_t)(breakpara->outputautostate & TIMER_CCHP0_OAEN)) |
                                                ((uint32_t)(breakpara->protectmode & TIMER_CCHP0_PROT)) |
                                                ((uint32_t)(breakpara->breakstate & TIMER_CCHP0_BRKEN)) |
                                                (((uint32_t)(breakpara->breakfilter) << 16U) & TIMER_CCHP0_BRKF) |
                                                ((uint32_t)(breakpara->breakpolarity & TIMER_CCHP0_BRKP)));
        } else {
            /* illegal parameters */
		
V1.0.4:
        breakpara->protectmode           = TIMER_CCHP0_PROT_OFF;
        breakpara->breakstate            = TIMER_BREAK_DISABLE;
        breakpara->breakfilter           = 0U;
        breakpara->breakpolarity         = TIMER_BREAK_POLARITY_LOW;
        breakpara->channelbreakstate     = TIMER_CH_BREAK_DISABLE;
        breakpara->channelbreakpolarity  = TIMER_CH_BREAK_POLARITY_LOW;
    }
}
...
                                                (((uint32_t)(breakpara->breakfilter) << 16U) & TIMER_CCHP0_BRKF) |
                                                ((uint32_t)(breakpara->breakpolarity & TIMER_CCHP0_BRKP)) |
                                                ((uint32_t)(breakpara->channelbreakstate & TIMER_CCHP0_CHBRKEN)) |
                                                ((uint32_t)(breakpara->channelbreakpolarity & TIMER_CCHP0_CHBRKP)));
        } else {
            /* illegal parameters */
____________________________________________________________________________________________________________________


******************* V1.0.3 2025-12-17 ************************************************************************************
______________________USART______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_usart.h
Fix reason:
Adapt to HAL xbuilder for case modification
V1.0.2:
#define USART_OSB_1bit                CTL2_OSB(1)                      /*!< 1 bit */
#define USART_OSB_3bit                CTL2_OSB(0)                      /*!< 3 bits */
V1.0.3:
#define USART_OSB_1BIT                CTL2_OSB(1)                      /*!< 1 bit */
#define USART_OSB_3BIT                CTL2_OSB(0)                      /*!< 3 bits */
	
______________________Common______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/system_gd32f50x.c
Fix reason:
adapter 280M for GD32F505, fix SystemCoreClockUpdate function
V1.0.2:
/
V1.0.3:
static void system_clock_280m_irc8m(void)
...
static void system_clock_280m_hxtal(void)
...
	
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_syscfg.h
Fix reason:
The name of the decoder has been changed to non-quardrature decoder
V1.0.2:
#define TIMER_DECODER_MODE0                 ((uint8_t)0x09U)                                       /*!< decoder mode 0 */
#define TIMER_DECODER_MODE1                 ((uint8_t)0x0AU)                                       /*!< decoder mode 1 */
#define TIMER_DECODER_MODE2                 ((uint8_t)0x0BU)                                       /*!< decoder mode 2 */
#define TIMER_DECODER_MODE3                 ((uint8_t)0x0CU)                                       /*!< decoder mode 3 */
V1.0.3:
#define TIMER_NONQUAD_DECODER_MODE0         ((uint8_t)0x09U)                                       /*!< non-quadrature decoder mode 0 */
#define TIMER_NONQUAD_DECODER_MODE1         ((uint8_t)0x0AU)                                       /*!< non-quadrature decoder mode 1 */
#define TIMER_NONQUAD_DECODER_MODE2         ((uint8_t)0x0BU)                                       /*!< non-quadrature decoder mode 2 */
#define TIMER_NONQUAD_DECODER_MODE3         ((uint8_t)0x0CU)                                       /*!< non-quadrature decoder mode 3 */
	
______________________Timer______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_timer.h
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_timer.c
Fix reason:
The name of the decoder has been changed to  non-quardrature decoder
V1.0.2:
void timer_decoder_mode_config(...)
V1.0.3:
void timer_non_quadrature_decoder_mode_config(...)

______________________CAN______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_can.c
Fix reason:
Fixed the bug of CAN message cancellation
V1.0.2:
        CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
        while((CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) && (0U != timeout)) {
            timeout--;
V1.0.3:
        if((CAN_CTL_TFO == (CAN_CTL(can_periph) & CAN_CTL_TFO)) && (CAN_TSTAT_TMLS0 == (CAN_TSTAT(can_periph) & (CAN_TSTAT_TMLS0 | CAN_ALL_MAILBOX_EMPTY)))){
            reval = ERROR;
        } else {
            CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
            while((CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)) && (0U != timeout)) {
                timeout--;
            }
            if(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)){
                reval = ERROR;
            }
	
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_can.c
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_can.h
Fix reason:
Fixed the bug of CAN message cancellation
V1.0.2:
void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number);
V1.0.3:
ErrStatus can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number);

Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_can.h
Fix reason:
Fixed the bug of CAN message cancellation
V1.0.2:
/
V1.0.3:
/* CAN maibox empty status mask */
#define CAN_ALL_MAILBOX_EMPTY              ((uint32_t)0x1C000000U)      /*!< CAN maibox empty status mask */


******************* V1.0.2 2025-11-21 ************************************************************************************
______________________BKP______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Examples/BKP/Backup_data/main.c
Fix reason:
If the RCU_BDCTL_BKPRST position reads BKP_DATAx at a certain time, it will cause the MCU to crash or go out of control. 
Before accessing the content of the backup domain, it is necessary to first determine whether the RCU_BDCTL_BKPRST bit 
has been reset to zero. If it is set, it should be cleared.
V1.0.1:
\
V1.0.2:
    /* confirm RCU_BDCTL_BKPRST bit is reset */
    if(RESET != (RCU_BDCTL & RCU_BDCTL_BKPRST)) {
        rcu_bkp_reset_disable();
    }
	
Fix file:
GD32F50x_Firmware_Library/Examples/BKP/Tamper/main.c
Fix reason:
If the RCU_BDCTL_BKPRST position reads BKP_DATAx at a certain time, it will cause the MCU to crash or go out of control. 
Before accessing the content of the backup domain, it is necessary to first determine whether the RCU_BDCTL_BKPRST bit 
has been reset to zero. If it is set, it should be cleared.
V1.0.1:
\
V1.0.2:
    /* confirm RCU_BDCTL_BKPRST bit is reset */
    if(RESET != (RCU_BDCTL & RCU_BDCTL_BKPRST)) {
        rcu_bkp_reset_disable();
    }
	
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_bkp.c
Fix reason:
The \param[in] parameter is missing in the comment above the bkp_write_data() function: ['data']
V1.0.1:
      \arg        BKP_DATA_x(x = 0..41): bkp data register number x
    \param[out] none
    \retval     none
V1.0.2:
      \arg        BKP_DATA_x(x = 0..41): bkp data register number x
    \param[in]  data: the data to be write in BKP data register
    \param[out] none
    \retval     none

______________________CAN______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_can.c
Fix reason:
Baseline Version Upgrade for some code
V1.0.1:
      \arg        CAN_MAILBOX(x=0,1,2)
	  
	\param[in]  can_working_mode
	  
      \arg        CAN_INT_WU: wakeup interrupt enable
V1.0.2:
      \arg        CAN_MAILBOXx(x=0,1,2) 	
	  
    \param[in]  working_mode
	
      \arg        CAN_INT_WAKEUP: wakeup interrupt enable

______________________TIMER______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_timer.c
Fix reason:
3223X FW TIMER update in 2025/11/13
V1.0.1:
    \param[in]  cssel: commutation control shadow register selection
V1.0.2:
    \param[in]  ccssel: commutation control shadow register selection
	  
______________________I2C______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_i2c.c
Fix reason:
Modification of I2C firmware library function comments
V1.0.1:
    \param[in]  i2c_periph: I2Cx(x=0,1)
    \param[in]  none
    \param[out] none
    \retval     none
V1.0.2:
    \param[in]  i2c_periph: I2Cx(x=0,1)
    \param[out] none
    \retval     none
	  
______________________DAC______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_dac.c
Fix reason:
3223X dac_software_trigger_enable add \param[out] none
V1.0.1:
    \param[in]  dac_out: DAC_OUTx(x=0)
    \retval     none
V1.0.2:
    \param[in]  dac_out: DAC_OUTx(x=0)
    \param[out] none
    \retval     none

______________________DMA______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_dma.h
Fix reason:
Modifying Content modify triger source
V1.0.1:
#define DMAMUX_TRIGGER_EXTI0_IT           RG_CHXCFG_TID(4U)                                                            /*!< trigger input is EXTI0 */
#define DMAMUX_TRIGGER_EXTI1_IT           RG_CHXCFG_TID(5U)                                                            /*!< trigger input is EXTI1 */
#define DMAMUX_TRIGGER_EXTI2_IT           RG_CHXCFG_TID(6U)                                                            /*!< trigger input is EXTI2 */
#define DMAMUX_TRIGGER_EXTI3_IT           RG_CHXCFG_TID(7U)                                                            /*!< trigger input is EXTI3 */
#define DMAMUX_TRIGGER_EXTI4_IT           RG_CHXCFG_TID(8U)                                                            /*!< trigger input is EXTI4 */
#define DMAMUX_TRIGGER_EXTI5_IT           RG_CHXCFG_TID(9U)                                                            /*!< trigger input is EXTI5 */
#define DMAMUX_TRIGGER_EXTI6_IT           RG_CHXCFG_TID(10U)                                                           /*!< trigger input is EXTI6 */
#define DMAMUX_TRIGGER_EXTI7_IT           RG_CHXCFG_TID(11U)                                                           /*!< trigger input is EXTI7 */
#define DMAMUX_TRIGGER_EXTI0_EVT          RG_CHXCFG_TID(12U)                                                           /*!< trigger input is EXTI8 */
#define DMAMUX_TRIGGER_EXTI1_EVT          RG_CHXCFG_TID(13U)                                                           /*!< trigger input is EXTI9 */
#define DMAMUX_TRIGGER_EXTI2_EVT          RG_CHXCFG_TID(14U)                                                           /*!< trigger input is EXTI10 */
#define DMAMUX_TRIGGER_EXTI3_EVT          RG_CHXCFG_TID(15U)                                                           /*!< trigger input is EXTI11 */
#define DMAMUX_TRIGGER_EXTI4_EVT          RG_CHXCFG_TID(16U)                                                           /*!< trigger input is EXTI12 */
#define DMAMUX_TRIGGER_EXTI5_EVT          RG_CHXCFG_TID(17U)                                                           /*!< trigger input is EXTI13 */
#define DMAMUX_TRIGGER_EXTI6_EVT          RG_CHXCFG_TID(18U)                                                           /*!< trigger input is EXTI14 */
#define DMAMUX_TRIGGER_EXTI7_EVT          RG_CHXCFG_TID(19U)                                                           /*!< trigger input is EXTI15 */

V1.0.2:
#define DMAMUX_TRIGGER_EXTI0_IT           RG_CHXCFG_TID(4U)                                                            /*!< interrupt trigger input is EXTI0 */
#define DMAMUX_TRIGGER_EXTI1_IT           RG_CHXCFG_TID(5U)                                                            /*!< interrupt trigger input is EXTI1 */
#define DMAMUX_TRIGGER_EXTI2_IT           RG_CHXCFG_TID(6U)                                                            /*!< interrupt trigger input is EXTI2 */
#define DMAMUX_TRIGGER_EXTI3_IT           RG_CHXCFG_TID(7U)                                                            /*!< interrupt trigger input is EXTI3 */
#define DMAMUX_TRIGGER_EXTI4_IT           RG_CHXCFG_TID(8U)                                                            /*!< interrupt trigger input is EXTI4 */
#define DMAMUX_TRIGGER_EXTI5_IT           RG_CHXCFG_TID(9U)                                                            /*!< interrupt trigger input is EXTI5 */
#define DMAMUX_TRIGGER_EXTI6_IT           RG_CHXCFG_TID(10U)                                                           /*!< interrupt trigger input is EXTI6 */
#define DMAMUX_TRIGGER_EXTI7_IT           RG_CHXCFG_TID(11U)                                                           /*!< interrupt trigger input is EXTI7 */
#define DMAMUX_TRIGGER_EXTI0_EVT          RG_CHXCFG_TID(12U)                                                           /*!< event trigger input is EXTI0 */
#define DMAMUX_TRIGGER_EXTI1_EVT          RG_CHXCFG_TID(13U)                                                           /*!< event trigger input is EXTI1 */
#define DMAMUX_TRIGGER_EXTI2_EVT          RG_CHXCFG_TID(14U)                                                           /*!< event trigger input is EXTI2 */
#define DMAMUX_TRIGGER_EXTI3_EVT          RG_CHXCFG_TID(15U)                                                           /*!< event trigger input is EXTI3 */
#define DMAMUX_TRIGGER_EXTI4_EVT          RG_CHXCFG_TID(16U)                                                           /*!< event trigger input is EXTI4 */
#define DMAMUX_TRIGGER_EXTI5_EVT          RG_CHXCFG_TID(17U)                                                           /*!< event trigger input is EXTI5 */
#define DMAMUX_TRIGGER_EXTI6_EVT          RG_CHXCFG_TID(18U)                                                           /*!< event trigger input is EXTI6 */
#define DMAMUX_TRIGGER_EXTI7_EVT          RG_CHXCFG_TID(19U)                                                           /*!< event trigger input is EXTI7 */

Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Include/gd32f50x_dma.c
Fix reason:
Modifying Content modify triger source
V1.0.1:
      \arg        DMA_FLAG_G: global interrupt flag of channel
	  
      \arg        DMA_INT_FLAG_G: global interrupt flag of channel
	  
V1.0.2:
      \arg        DMA_FLAG_GIF: global interrupt flag of channel
	  
      \arg        DMA_INT_FLAG_GIF: global interrupt flag of channel
	  
______________________Common______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/GCC/startup_gd32f50x.S
Fix reason:
Modify the initialized SRAM capacity from full to 32K
V1.0.1:
  ldr     r0, =0x1ffff7e0
  ldr     r2, [r0]
  ldr     r0, =0xffff0000
  and     r2, r2, r0
  lsr     r2, r2, #16
  lsl     r2, r2, #10
V1.0.2:
  mov     r2, #0x8000   
  
Fix file:
GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/system_gd32f50x.c
Fix reason:
Add comment for notion of frequency switching
V1.0.1:
#if (defined(GD32F503) || defined(GD32F505))
//#define __SYSTEM_CLOCK_IRC8M                    (uint32_t)(__IRC8M)
//#define __SYSTEM_CLOCK_HXTAL                    (uint32_t)(__HXTAL)
//#define __SYSTEM_CLOCK_200M_PLL_IRC8M           (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_200M_PLL_HXTAL           (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_220M_PLL_IRC8M           (uint32_t)(220000000)
//#define __SYSTEM_CLOCK_220M_PLL_HXTAL           (uint32_t)(220000000)
//#define __SYSTEM_CLOCK_252M_PLL_IRC8M           (uint32_t)(252000000)
#define __SYSTEM_CLOCK_252M_PLL_HXTAL           (uint32_t)(252000000)
#endif /* GD32F503 */
V1.0.2:
#if (defined(GD32F502) || defined(GD32F503) || defined(GD32F505))
//#define __SYSTEM_CLOCK_IRC8M                    (uint32_t)(__IRC8M)
//#define __SYSTEM_CLOCK_HXTAL                    (uint32_t)(__HXTAL)
//#define __SYSTEM_CLOCK_200M_PLL_IRC8M           (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_200M_PLL_HXTAL           (uint32_t)(200000000)
#endif /* GD32F502 || GD32F503 || GD32F505 */

#if (defined(GD32F503) || defined(GD32F505))
//#define __SYSTEM_CLOCK_220M_PLL_IRC8M           (uint32_t)(220000000)
//#define __SYSTEM_CLOCK_220M_PLL_HXTAL           (uint32_t)(220000000)
//#define __SYSTEM_CLOCK_252M_PLL_IRC8M           (uint32_t)(252000000)
#define __SYSTEM_CLOCK_252M_PLL_HXTAL           (uint32_t)(252000000)
#endif /* GD32F503 || GD32F505 */

Fix file:
GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/system_gd32f50x.c
Fix reason:
use macro operation to prevent special scatter loader (such as fmc interface load to sram but main code in flash)
V1.0.1:
    fmc_bank0_unlock();
    fmc_nwa_enable();
    fmc_bank0_lock();
V1.0.2:
    if((RESET != (FMC_CTL0 & FMC_CTL0_LK))) {
        /* write the FMC unlock key */
        FMC_KEY0 = UNLOCK_KEY0;
        FMC_KEY0 = UNLOCK_KEY1;
    }
    FMC_CTL0 |= FMC_CTL0_NWLDE;
    FMC_CTL0 |= FMC_CTL0_LK;
	
Fix file:
GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/system_gd32f50x.c
Fix reason:
Add comment for notion of frequency switching
V1.0.1:
    /* AHB = SYSCLK/4 */
V1.0.2:
    /* AHB = SYSCLK/4. AHB clock will be modified to SYSCLK after frequency switching finished to prevent Vcore fluctuations */
	
______________________FMC______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Examples/FMC/Erase_Program/main.c
Fix reason:
add clear all pending flags operation before program flash
V1.0.1:
    fmc_unlock();

    address = FMC_WRITE_START_ADDR;
V1.0.2:
    fmc_unlock();
    /* clear all pending flags */
    fmc_flag_clear(FMC_FLAG_BANK0_END);
    fmc_flag_clear(FMC_FLAG_BANK0_WPERR);
    fmc_flag_clear(FMC_FLAG_BANK0_PGERR);

    address = FMC_WRITE_START_ADDR;

______________________USB______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Examples/USBFS/USB_Device/dev_firmware_update/src/app.c
GD32F50x_Firmware_Library/Examples/USBFS/USB_Device/in_application_program_hid/src/app.c
Fix reason:
keil IDE configuration modify
V1.0.1:
            app_addr = *(__IO uint32_t*) (APP_LOADED_ADDR + 4U);
            application = (app_func) app_addr;

            /* initialize user application's stack pointer */
            __set_MSP(*(__IO uint32_t *)APP_LOADED_ADDR);

V1.0.2:
            /* initialize user application's stack pointer */
            __set_MSP(*(__IO uint32_t *)APP_LOADED_ADDR);
            
            app_addr = *(__IO uint32_t*) (APP_LOADED_ADDR + 4U);
            application = (app_func) app_addr;

______________________RCU______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Examples/RCU/System_clock_switch/main.c
Fix reason:
Add comment for notion of frequency switching
V1.0.1:
    /* AHB = SYSCLK/4 */

V1.0.2:
    /* AHB = SYSCLK/4. AHB clock will be modified to SYSCLK after frequency switching finished to prevent Vcore fluctuations */

Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_rcu.c
Fix reason:
modify pll11_mul to  pll1_mul 
V1.0.1:
    \param[in]  pll11_mul: PLL1 clock multiplication factor

V1.0.2:
    \param[in]  pll1_mul: PLL1 clock multiplication factor
______________________TIMER______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_timer.h
Fix reason:
FW bug fixed in 2025/11/25
V1.0.1:

V1.0.2:
#define TIMER_IC_SELECTION_PAIR             ((uint16_t)0x0004U)                     /*!< channel y is configured as input and icy is mapped on the other channel of same pair */

Fix file:
GD32F50x_Firmware_Library/Firmware/GD32F50x_standard_peripheral/Source/gd32f50x_timer.c
Fix reason:
FW bug fixed in 2025/11/25
V1.0.1:
            TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpara->icselection) & TIMER_CHCTL0_CH0MS);

V1.0.2:
            if(TIMER_IC_SELECTION_PAIR == icpara->icselection) {
                TIMER_CHCTL0(timer_periph) |= (uint32_t)(((uint32_t)(icpara->icselection) << 28U) & TIMER_CHCTL0_CH0MS);
            } else {
                TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpara->icselection) & TIMER_CHCTL0_CH0MS);
            }

******************* V1.0.1 2025-11-03 ******************************************************************************************
______________________Common______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Utilities/gd32f503v_eval.c
Fix reason:
Add AF configuration in USART initialization
V1.0.0:
void gd_eval_com_init(uint32_t com)
{
    uint32_t com_id = 0U;
    if(EVAL_COM0 == com) {
        com_id = 0U;
    } else {
        /* do nothing */
    }

    /* enable GPIO clock */
    rcu_periph_clock_enable(COM_GPIO_CLK[com_id]);

    /* enable USART clock */
    rcu_periph_clock_enable(COM_CLK[com_id]);
    rcu_periph_clock_enable(RCU_AF);

    /* connect port to USARTx_Tx */
    gpio_mode_set(COM_GPIO_PORT[com_id],GPIO_MODE_AF,GPIO_PUPD_NONE,COM_TX_PIN[com_id]);
    gpio_output_options_set(COM_GPIO_PORT[com_id], GPIO_OTYPE_PP, GPIO_OSPEED_LEVEL3, COM_TX_PIN[com_id]);

    /* connect port to USARTx_Rx */
    gpio_mode_set(COM_GPIO_PORT[com_id],GPIO_MODE_AF,GPIO_PUPD_NONE,COM_RX_PIN[com_id]);
    gpio_output_options_set(COM_GPIO_PORT[com_id], GPIO_OTYPE_PP, GPIO_OSPEED_LEVEL3, COM_RX_PIN[com_id]);

    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com, 115200U);
    usart_receive_config(com, USART_RECEIVE_ENABLE);
    usart_transmit_config(com, USART_TRANSMIT_ENABLE);
    usart_enable(com);
}
V1.0.1:
void gd_eval_com_init(uint32_t com)
{
    uint32_t com_id = 0U;
    if(EVAL_COM0 == com) {
        com_id = 0U;
    } else {
        /* do nothing */
    }

    /* enable GPIO clock */
    rcu_periph_clock_enable(COM_GPIO_CLK[com_id]);

    /* enable USART clock */
    rcu_periph_clock_enable(COM_CLK[com_id]);
    rcu_periph_clock_enable(RCU_AF);
    
    /* connect port to USARTx_Tx */
    gpio_af_set(COM_GPIO_PORT[com_id], EVAL_COM_AF, COM_TX_PIN[com_id]);

    /* connect port to USARTx_Rx */
    gpio_af_set(COM_GPIO_PORT[com_id], EVAL_COM_AF, COM_RX_PIN[com_id]);

    /* connect port to USARTx_Tx */
    gpio_mode_set(COM_GPIO_PORT[com_id],GPIO_MODE_AF,GPIO_PUPD_NONE,COM_TX_PIN[com_id]);
    gpio_output_options_set(COM_GPIO_PORT[com_id], GPIO_OTYPE_PP, GPIO_OSPEED_LEVEL3, COM_TX_PIN[com_id]);

    /* connect port to USARTx_Rx */
    gpio_mode_set(COM_GPIO_PORT[com_id],GPIO_MODE_AF,GPIO_PUPD_NONE,COM_RX_PIN[com_id]);
    gpio_output_options_set(COM_GPIO_PORT[com_id], GPIO_OTYPE_PP, GPIO_OSPEED_LEVEL3, COM_RX_PIN[com_id]);

    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com, 115200U);
    usart_receive_config(com, USART_RECEIVE_ENABLE);
    usart_transmit_config(com, USART_TRANSMIT_ENABLE);
    usart_enable(com);
}

Fix file:
GD32F50x_Firmware_Library/Utilities/gd32f503v_eval.h
Fix reason:
Add AF configuration in USART initialization
V1.0.0:
#define EVAL_COM0                        USART0
#define EVAL_COM0_CLK                    RCU_USART0
#define EVAL_COM0_TX_PIN                 GPIO_PIN_9
#define EVAL_COM0_RX_PIN                 GPIO_PIN_10
#define EVAL_COM0_GPIO_PORT              GPIOA
#define EVAL_COM0_GPIO_CLK               RCU_GPIOA
V1.0.1:
#define EVAL_COM0                        USART0
#define EVAL_COM0_CLK                    RCU_USART0
#define EVAL_COM0_TX_PIN                 GPIO_PIN_9
#define EVAL_COM0_RX_PIN                 GPIO_PIN_10
#define EVAL_COM0_GPIO_PORT              GPIOA
#define EVAL_COM0_GPIO_CLK               RCU_GPIOA
#define EVAL_COM_AF                      GPIO_AF_0


______________________USART______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Examples/USART/IDLE_receive_interrupt/main.c
Fix reason:
After enabling USART, the IDLE flag will be set once. Add operations to wait for the IDLE flag to be set and clear the flag after initialization.
V1.0.0:
    /* initialize DMA */
    dma_config();
    
    /* initialize USART */
    usart_config();

    usart_interrupt_enable(USART0, USART_INT_IDLE);
V1.0.1:
    /* initialize DMA */
    dma_config();
    
    /* initialize USART */
    usart_config();

    /* wait IDLE flag set and clear it */
    while(RESET == usart_flag_get(USART0, USART_FLAG_IDLE)) {
    }
    /* clear IDLE flag */
    usart_data_receive(USART0);

    usart_interrupt_enable(USART0, USART_INT_IDLE);

______________________SYSCFG______________________________________________________________________________________________
Fix file:
GD32F50x_Firmware_Library/Firmware/CMSIS/GD/GD32F50x/Source/system_gd32f50x.c
Fix reason:
add fmc_lock and 220Mhz by FAE requirement
V1.0.0:
    /* enable no waiting time area load after system reset */
    fmc_bank0_unlock();
    fmc_nwa_enable();
	
V1.0.1
    /* enable no waiting time area load after system reset */
    fmc_bank0_unlock();
    fmc_nwa_enable();
    fmc_bank0_lock();
	
#elif defined (__SYSTEM_CLOCK_220M_PLL_IRC8M)
/*!
    \brief      configure the system clock to 220M by PLL0 which selects IRC8M as its clock source
    \param[in]  none
    \param[out] none
    \retval     none
    \note       This function contains scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
static void system_clock_220m_irc8m(void)
{
    uint32_t timeout = 0U;
    uint32_t stab_flag = 0U;
    __IO uint32_t reg_temp;

    /* enable IRC8M */
    RCU_CTL |= RCU_CTL_IRC8MEN;

    /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */
    do {
        timeout++;
        stab_flag = (RCU_CTL & RCU_CTL_IRC8MSTB);
    } while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout));

    /* if fail */
    if(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)) {
        while(1) {
        }
    }

    /* LDO output voltage high mode */
    RCU_APB1EN |= RCU_APB1EN_PMUEN;
    PMU_CTL0 |= PMU_CTL0_LDOVS;

    /* IRC8M is stable */
    /* AHB = SYSCLK / 4 */
    RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
    /* APB2 = AHB/1 */
    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
    /* APB1 = AHB/2 */
    RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;

    /* CK_PLL = (CK_IRC8M)/2 * 55 = 220 MHz */
    RCU_CFG1 &= ~(RCU_CFG1_PLL0SEL | RCU_CFG1_PREDIV0 | RCU_CFG1_PREDIV1);
    RCU_CFG1 |= (RCU_PLL0SRC_IRC8M  |  RCU_PREDIV0_DIV2);
    RCU_CFG0 &= ~(RCU_CFG0_PLL0MF_0_3 | RCU_CFG0_PLL0MF_4_5);
    RCU_CFG0 |= RCU_PLL0_MUL55;

    /* enable PLL0 */
    RCU_CTL |= RCU_CTL_PLL0EN;

    /* wait until PLL0 is stable */
    while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
    }

    /* select FMC clock is CK_AHB and div is 1 */
    RCU_ADDCTL &= ~(RCU_ADDCTL_FMCSEL | RCU_ADDCTL_FMCDIV);
    RCU_ADDCTL |=  RCU_FMC_CK_AHB | RCU_FMC_DIV1;

    reg_temp = RCU_CFG0;
    /* select PLL0P as system clock */
    reg_temp &= ~RCU_CFG0_SCS;
    reg_temp |= RCU_CKSYSSRC_PLL0P;
    RCU_CFG0 = reg_temp;

    /* wait until PLL0 is selected as system clock */
    while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
    }

    RCU_MODIFY_UP_2(0x50);
}

#elif defined (__SYSTEM_CLOCK_220M_PLL_HXTAL)
/*!
    \brief      configure the system clock to 220M by PLL0 which selects HXTAL(8M) as its clock source
    \param[in]  none
    \param[out] none
    \retval     none
    \note       This function contains scenarios leading to an infinite loop.
                Modify according to the user's actual usage scenarios.
*/
static void system_clock_220m_hxtal(void)
{
    uint32_t timeout = 0U;
    uint32_t stab_flag = 0U;
    __IO uint32_t reg_temp;

    /* enable HXTAL */
    RCU_CTL |= RCU_CTL_HXTALEN;

    /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
    do {
        timeout++;
        stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
    } while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));

    /* if fail */
    if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)) {
        while(1) {
        }
    }

    RCU_APB1EN |= RCU_APB1EN_PMUEN;
    PMU_CTL0 |= PMU_CTL0_LDOVS;

    /* HXTAL is stable */
    /* AHB = SYSCLK/4 */
    RCU_CFG0 |= RCU_AHB_CKSYS_DIV4;
    /* APB2 = AHB/1 */
    RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
    /* APB1 = AHB/2 */
    RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;

    /* CK_PLL0P = (HXTAL)/2 * 55 = 220 MHz */
    RCU_CFG1 &= ~(RCU_CFG1_PLL0SEL | RCU_CFG1_PREDIV0 | RCU_CFG1_PREDIV1);
    RCU_CFG1 |= (RCU_PLL0SRC_HXTAL  |  RCU_PREDIV0_DIV2);
    RCU_CFG0 &= ~(RCU_CFG0_PLL0MF_0_3 | RCU_CFG0_PLL0MF_4_5);
    RCU_CFG0 |= RCU_PLL0_MUL55;


    /* enable PLL0 */
    RCU_CTL |= RCU_CTL_PLL0EN;

    /* wait until PLL0 is stable */
    while(0U == (RCU_CTL & RCU_CTL_PLL0STB)) {
    }

    /* select FMC clock is CK_AHB and div is 1 */
    RCU_ADDCTL &= ~(RCU_ADDCTL_FMCSEL | RCU_ADDCTL_FMCDIV);
    RCU_ADDCTL |=  RCU_FMC_CK_AHB | RCU_FMC_DIV1;

    reg_temp = RCU_CFG0;
    /* select PLL0P as system clock */
    reg_temp &= ~RCU_CFG0_SCS;
    reg_temp |= RCU_CKSYSSRC_PLL0P;
    RCU_CFG0 = reg_temp;

    /* wait until PLL0 is selected as system clock */
    while(RCU_SCSS_PLL0P != (RCU_CFG0 & RCU_CFG0_SCSS)) {
    }

    RCU_MODIFY_UP_2(0x50U);
}
	